package com.ocm.tourism.core.dao.jpa;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.persistence.Query;

import org.springframework.stereotype.Repository;

import com.ocm.tourism.core.dao.CulinaryCultureDao;
import com.ocm.tourism.core.domain.BusinessType;
import com.ocm.tourism.core.domain.CulinaryCulture;
import com.ocm.tourism.core.domain.Distance;
import com.ocm.tourism.core.domain.FoodStall;
import com.ocm.tourism.core.model.FieldCriteria;

@Repository
public class JpaCulinaryCulterDao extends JpaGenericDao<CulinaryCulture> implements CulinaryCultureDao {

   public JpaCulinaryCulterDao() {
      this.setClazz(CulinaryCulture.class);
   }

   @SuppressWarnings("unchecked")
   public List<CulinaryCulture> findAll(List<Long> culinaryCultureIds) {
      Query query = this.entityManager().createQuery("SELECT b FROM CulinaryCulture b WHERE b.id IN (:ids)", CulinaryCulture.class);
      query.setParameter("ids", culinaryCultureIds);
      List<CulinaryCulture> businesses = query.getResultList();
      return businesses;
   }
   
   @Override
   public long count(BusinessType businessType) {
      Query query = this.entityManager().createQuery("SELECT COUNT(b) FROM CulinaryCulture b WHERE b.businessType =:businessType", Long.class);
      query.setParameter("businessType", businessType);
      long count = (Long) query.getSingleResult();
      return count;
   }

   @Override
   public long count(BusinessType businessType, long participantId) {
      Query query = this.entityManager().createQuery("SELECT COUNT(b) FROM CulinaryCulture b WHERE b.businessType =:businessType AND b.participant.id=:participantId", Long.class);
      query.setParameter("businessType", businessType);
      query.setParameter("participantId", participantId);
      long count = (Long) query.getSingleResult();
      return count;
   }

   @SuppressWarnings("unchecked")
   public List<CulinaryCulture> find(int firstResult, int maxResults, BusinessType businessType) {
      Query query = this.entityManager().createQuery("SELECT b FROM CulinaryCulture b WHERE b.businessType =:businessType", CulinaryCulture.class).setFirstResult(firstResult).setMaxResults(maxResults);
      query.setParameter("businessType", businessType);
      List<CulinaryCulture> businesses = query.getResultList();
      return businesses;
   }

   @SuppressWarnings("unchecked")
   @Override
   public List<CulinaryCulture> find(int firstResult, int maxResults, BusinessType businessType, long participantId) {
      Query query = this.entityManager().createQuery("SELECT b FROM CulinaryCulture b WHERE b.businessType =:businessType AND b.participant.id=:participantId", CulinaryCulture.class).setFirstResult(firstResult).setMaxResults(maxResults);
      query.setParameter("businessType", businessType);
      query.setParameter("participantId", participantId);
      List<CulinaryCulture> businesses = query.getResultList();
      return businesses;
   }
   
   @SuppressWarnings("unchecked")
   public List<CulinaryCulture> find(int firstResult, int maxResults, BusinessType... businessTypes) {
      Query query = this.entityManager().createQuery("SELECT b FROM CulinaryCulture b WHERE b.businessType IN (:businessTypes)", CulinaryCulture.class).setFirstResult(firstResult).setMaxResults(maxResults);
      query.setParameter("businessTypes", Arrays.asList(businessTypes));
      List<CulinaryCulture> businesses = query.getResultList();
      return businesses;
   }
   
   @SuppressWarnings("unchecked")
   public List<Distance> findDistances(long culinaryCulture) {
      Query query = this.entityManager().createQuery("SELECT r FROM Distance r WHERE r.culinaryCulture.id =:culinaryCulture", Distance.class);
      query.setParameter("culinaryCulture", culinaryCulture);
      List<Distance> distances = query.getResultList();
      return distances;
   }

   @Override
   public FoodStall findFoodStall(long id) {
      FoodStall foodStall = this.entityManager.find(FoodStall.class, id);
      return foodStall;
   }

   @SuppressWarnings("unchecked")
   public List<FoodStall> findFoodStalls(int firstResult, int maxResults) {
      Query query = this.entityManager().createQuery("SELECT b FROM CulinaryCulture b WHERE b.businessType =:businessType", CulinaryCulture.class).setFirstResult(firstResult).setMaxResults(maxResults);
      query.setParameter("businessType", BusinessType.FOODSTALL);
      List<FoodStall> businesses = query.getResultList();
      return businesses;
   }

   @SuppressWarnings("unchecked")
   public List<FoodStall> findFoodStalls(int firstResult, int maxResults, long participantId) {
      Query query = this.entityManager().createQuery("SELECT b FROM CulinaryCulture b WHERE b.businessType =:businessType AND b.participant.id=:participantId", CulinaryCulture.class).setFirstResult(firstResult).setMaxResults(maxResults);
      query.setParameter("businessType", BusinessType.FOODSTALL);
      query.setParameter("participantId", participantId);
      List<FoodStall> businesses = query.getResultList();
      return businesses;
   }

   @SuppressWarnings("unchecked")
   public List<CulinaryCulture> findCulinaryCultures(List<FieldCriteria> criterias) {
      String sql = "SELECT b FROM Hotel CulinaryCulture WHERE b.businessType IN (:businessTypes)";
      for (FieldCriteria criteria : criterias){
         sql = criteria.appendCritera(sql);
      }
      sql = sql + "ORDER BY b.createdDate DESC";
      Query query = this.entityManager().createQuery(sql, CulinaryCulture.class);
      List<BusinessType> businessTypes = new ArrayList<BusinessType>();
      businessTypes.add(BusinessType.COFFEE);
      businessTypes.add(BusinessType.RESTAURANT);
      businessTypes.add(BusinessType.FOODSTALL);
      query.setParameter("businessTypes", businessTypes);
      for (FieldCriteria criteria : criterias){
         query.setParameter(criteria.getName(), criteria.getValue());
      }
      List<CulinaryCulture> businesses = query.getResultList();
      return businesses;
   }
}
